/* simple ping program 1 way communication*/
#include <stdio.h>
#include "mpi.h"
#include <stdlib.h>
#define TIM 100

main(int argc, char **argv)
{
int i,size,rank,j;
MPI_Status err;
void *msg;
float t1,t2;
int STT,STP,INC;
int sizei;
float speed;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

if ((size !=2) && (rank==0) ) {
  printf("Error, wrong comm size, need excactly 2 processes\n");
  MPI_Finalize();
  return -1;
}

if (rank ==0){ /*  ping  */
  t1 = MPI_Wtick();
  printf("Wall clock accuracy = %12.11f \n",t1);
  printf("Enter shortest length : "); scanf("%d",&STT);
  printf("Enter longest length  : "); scanf("%d",&STP);
  printf("Enter step            : "); scanf("%d",&INC);
  MPI_Send (&STT,1,MPI_INT,1,5,MPI_COMM_WORLD);
  MPI_Send (&STP,1,MPI_INT,1,6,MPI_COMM_WORLD);
  MPI_Send (&INC,1,MPI_INT,1,7,MPI_COMM_WORLD);
  msg = malloc(STP*sizeof(i));
  if (msg==NULL) 
  {
   MPI_Finalize(); 
   printf("memory alloc error\n"); 
   return -1 ;
  }
  for (i=STT;i<=STP;i+=INC){
     t1 = MPI_Wtime();
     for (j=0;j<TIM;j++){
     MPI_Send (msg,i,MPI_INT,1,1,MPI_COMM_WORLD);
     MPI_Recv (msg,i,MPI_INT,1,2,MPI_COMM_WORLD,&err);}
     t2 = MPI_Wtime();
     t2 -= t1;
  sizei = 2 * sizeof(i)*i*8*100;
  speed = sizei / t2 /1000000;
  printf("%20d %30f\n",i,speed);
  }
  printf("each test was repeated %d times \n",TIM);
}
else { /*  pong  */
  MPI_Recv (&STT,1,MPI_INT,0,5,MPI_COMM_WORLD,&err);
  MPI_Recv (&STP,1,MPI_INT,0,6,MPI_COMM_WORLD,&err);
  MPI_Recv (&INC,1,MPI_INT,0,7,MPI_COMM_WORLD,&err);
  msg = malloc(STP*sizeof(i));
  if (msg==NULL)
   {
   MPI_Finalize(); 
   printf("memory alloc error\n");
   return -1 ;
   }
  for (i=STT;i<=STP;i+=INC)
  {
  for (j=0;j<TIM;j++)
     {
     MPI_Recv (msg,i,MPI_INT,0,1,MPI_COMM_WORLD,&err);
     MPI_Send (msg,i,MPI_INT,0,2,MPI_COMM_WORLD);}
     }

}
MPI_Finalize();
printf("SUCCESS\n");
return 0;
}

